From c3a0162b754681241bcf70b392e80aeede36faab Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 25 Feb 2026 12:40:22 +0200 Subject: [PATCH] [PATCH 11/24] lib-var-expand: Add "safe" filter to prevent escaping output For example ldap_base = %{passdb:next_dn | safe} to avoid escaping the DN. Gbp-Pq: Name CVE-2026-24031-27860-8.patch --- src/lib-var-expand/expansion-filter.c | 9 +++++++++ src/lib-var-expand/expansion-program.c | 3 ++- src/lib-var-expand/var-expand-private.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/lib-var-expand/expansion-filter.c b/src/lib-var-expand/expansion-filter.c index 7900057..93affeb 100644 --- a/src/lib-var-expand/expansion-filter.c +++ b/src/lib-var-expand/expansion-filter.c @@ -1130,6 +1130,14 @@ static int fn_text(const struct var_expand_statement *stmt, return 0; } +static int fn_safe(const struct var_expand_statement *stmt ATTR_UNUSED, + struct var_expand_state *state, + const char **error_r ATTR_UNUSED) +{ + state->transfer_safe = TRUE; + return 0; +} + static const struct var_expand_filter var_expand_builtin_filters[] = { { .name = "lookup", .filter = fn_lookup }, { .name = "literal", .filter = fn_literal }, @@ -1167,6 +1175,7 @@ static const struct var_expand_filter var_expand_builtin_filters[] = { { .name = "text", .filter = fn_text }, { .name = "encrypt", .filter = expansion_filter_encrypt }, { .name = "decrypt", .filter = expansion_filter_decrypt }, + { .name = "safe", .filter = fn_safe }, { .name = NULL } }; diff --git a/src/lib-var-expand/expansion-program.c b/src/lib-var-expand/expansion-program.c index 5f64b5b..6a05bc3 100644 --- a/src/lib-var-expand/expansion-program.c +++ b/src/lib-var-expand/expansion-program.c @@ -140,7 +140,8 @@ int var_expand_program_execute(string_t *dest, const struct var_expand_program * if (state.transfer_binary) var_expand_state_set_transfer(&state, binary_to_hex(state.transfer->data, state.transfer->used)); if (state.transfer_set) { - if (!program->only_literal && params->escape_func != NULL) { + if (!program->only_literal && !state.transfer_safe && + params->escape_func != NULL) { str_append(state.result, params->escape_func(str_c(state.transfer), params->escape_context)); diff --git a/src/lib-var-expand/var-expand-private.h b/src/lib-var-expand/var-expand-private.h index 26d30c6..ae3aef8 100644 --- a/src/lib-var-expand/var-expand-private.h +++ b/src/lib-var-expand/var-expand-private.h @@ -73,6 +73,7 @@ struct var_expand_state { string_t *transfer; bool transfer_set:1; bool transfer_binary:1; + bool transfer_safe:1; }; struct var_expand_statement { -- 2.30.2